﻿using MCM.Abstractions.FluentBuilder;
using MCM.Common;
using MarriageFertility.Texts;

namespace MarriageFertility.Mcm
{
    public static class SettingsMenu
    {
        private static int _groupIndex;

        public static ISettingsBuilder CreateBaseSettingsBuilder(string id, string folderName)
        {
            return BaseSettingsBuilder.Create(id, folderName)
                ?.SetFormat("xml")
                .SetFolderName(folderName)
                .SetSubFolder(folderName);
        }

        public static void AddMarriageSettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.MarriageConfig, groupBuilder => groupBuilder
                .AddInteger("MinimumMarriageAgeFeMale", CommonText.MinimumMarriageAgeFeMale, 10, 18,
                    new ProxyRef<int>(() => MCMSettings.Instance.MinimumMarriageAgeFeMale,
                        o => MCMSettings.Instance.MinimumMarriageAgeFeMale = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddInteger("MinimumMarriageAgeMale", CommonText.MinimumMarriageAgeMale, 10, 18,
                    new ProxyRef<int>(() => MCMSettings.Instance.MinimumMarriageAgeMale,
                        o => MCMSettings.Instance.MinimumMarriageAgeMale = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("AllowMoreSpouse", CommonText.AllowMoreSpouse,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableMoreSpouse,
                        o => MCMSettings.Instance.EnableMoreSpouse = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("AllowRelatedMarriage", CommonText.AllowRelatedMarriage,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableRelatedMarriage,
                        o => MCMSettings.Instance.EnableRelatedMarriage = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("AllowSameGender", CommonText.AllowSameGender,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableSameGender,
                        o => MCMSettings.Instance.EnableSameGender = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("JoinPlayerClan", CommonText.JoinPlayerClan,
                    new ProxyRef<bool>(() => MCMSettings.Instance.JoinPlayerClan,
                        o => MCMSettings.Instance.JoinPlayerClan = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("PersonRelation", RelationText.PersonRelation,
                    new ProxyRef<bool>(() => MCMSettings.Instance.PersonRelation,
                        o => MCMSettings.Instance.PersonRelation = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("EnableClearSpouse", CommonText.EnableClearSpouse,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableClearSpouse,
                        o => MCMSettings.Instance.EnableClearSpouse = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("LordAutoTrade", CommonText.LordAutoTrade,
                    new ProxyRef<bool>(() => MCMSettings.Instance.LordAutoTrade,
                        o => MCMSettings.Instance.LordAutoTrade = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("RelationCheat", CommonText.RelationCheat,
                    new ProxyRef<bool>(() => MCMSettings.Instance.RelationCheat,
                        o => MCMSettings.Instance.RelationCheat = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddNPcMarriageSettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.NpcMarriageConfig, groupBuilder => groupBuilder
                .AddFloatingInteger("BaseMarriageProbability", CommonText.BaseMarriageProbability, 0, 100,
                    new ProxyRef<float>(() => MCMSettings.Instance.BaseMarriageChanceForNPCs,
                        o => MCMSettings.Instance.BaseMarriageChanceForNPCs = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("OnlyPlayerMarryMore", CommonText.OnlyPlayerMarryMore,
                    new ProxyRef<bool>(() => MCMSettings.Instance.OnlyPlayerMarryMore,
                        o => MCMSettings.Instance.OnlyPlayerMarryMore = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("IgnoreKingdom", CommonText.IgnoreKingdom,
                    new ProxyRef<bool>(() => MCMSettings.Instance.IgnoreKingdom,
                        o => MCMSettings.Instance.IgnoreKingdom = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("IgnoreClan", CommonText.IgnoreClan,
                    new ProxyRef<bool>(() => MCMSettings.Instance.IgnoreClan,
                        o => MCMSettings.Instance.IgnoreClan = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddToggle("NPcMarriageToggle", CommonText.NpcMarriageConfig,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableNpcMarriageChance,
                        o => MCMSettings.Instance.EnableNpcMarriageChance = o),
                    boolBuilder => boolBuilder.SetRequireRestart(false).SetOrder(orderIndex++)
                ).SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddPregnancyBaseSettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.PregnancyBaseConfig, groupBuilder => groupBuilder
                .AddInteger("MinPregnancyAge", CommonText.MinAge, 12, 18,
                    new ProxyRef<int>(() => MCMSettings.Instance.MinPregnancyAge,
                        o => MCMSettings.Instance.MinPregnancyAge = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddInteger("MaxPregnancyAge", CommonText.MaxAge, 45, 100, new ProxyRef<int>(
                        () => MCMSettings.Instance.MaxPregnancyAge,
                        o => MCMSettings.Instance.MaxPregnancyAge = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddInteger("PregnancyDurationInDays", CommonText.PregnancyDurationInDays, 1, 100,
                    new ProxyRef<float>(
                        () => MCMSettings.Instance.PregnancyDurationInDays,
                        o => MCMSettings.Instance.PregnancyDurationInDays = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddFloatingInteger("MaternalMortalityProbabilityInLabor",
                    CommonText.MaternalMortalityProbabilityInLabor, 0, 100,
                    new ProxyRef<float>(
                        () => MCMSettings.Instance.MaternalMortalityProbabilityInLabor,
                        o => MCMSettings.Instance.MaternalMortalityProbabilityInLabor = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddFloatingInteger("StillbirthProbability",
                    CommonText.StillbirthProbability, 0, 100,
                    new ProxyRef<float>(
                        () => MCMSettings.Instance.StillbirthProbability,
                        o => MCMSettings.Instance.StillbirthProbability = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddFloatingInteger("DeliveringFemaleOffspringProbability",
                    CommonText.DeliveringFemaleOffspringProbability, 0, 100,
                    new ProxyRef<float>(
                        () => MCMSettings.Instance.DeliveringFemaleOffspringProbability,
                        o => MCMSettings.Instance.DeliveringFemaleOffspringProbability = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddFloatingInteger("DeliveringTwinsProbability",
                    CommonText.DeliveringTwinsProbability, 0, 100,
                    new ProxyRef<float>(
                        () => MCMSettings.Instance.DeliveringTwinsProbability,
                        o => MCMSettings.Instance.DeliveringTwinsProbability = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddInteger("PlayerMaxChildrenLimit", CommonText.PlayerMaxChildrenLimit, 0, 300,
                    new ProxyRef<int>(() => MCMSettings.Instance.PlayerMaxChildrenLimit,
                        o => MCMSettings.Instance.PlayerMaxChildrenLimit = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddInteger("LordMaxChildrenLimit", CommonText.LordMaxChildrenLimit, 0, 300,
                    new ProxyRef<int>(() => MCMSettings.Instance.LordMaxChildrenLimit,
                        o => MCMSettings.Instance.LordMaxChildrenLimit = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("ChildJoinMotherClan", CommonText.ChildJoinMotherClan,
                    new ProxyRef<bool>(() => MCMSettings.Instance.ChildJoinMotherClan,
                        o => MCMSettings.Instance.ChildJoinMotherClan = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddPregnancyProbabilitySettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.PregnancyProbabilityConfig, groupBuilder => groupBuilder
                .AddFloatingInteger("MainHeroProbability", CommonText.MainHeroProbability, 0, 100,
                    new ProxyRef<float>(() => MCMSettings.Instance.MainHeroProbability,
                        o => MCMSettings.Instance.MainHeroProbability = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddFloatingInteger("MainHeroClanProbability", CommonText.MainHeroClanProbability, 0, 100,
                    new ProxyRef<float>(() => MCMSettings.Instance.MainHeroClanProbability,
                        o => MCMSettings.Instance.MainHeroClanProbability = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddFloatingInteger("OtherHeroProbability", CommonText.OtherHeroProbability, 0, 100,
                    new ProxyRef<float>(() => MCMSettings.Instance.OtherHeroProbability,
                        o => MCMSettings.Instance.OtherHeroProbability = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddToggle("EnablePregnancyModify", CommonText.PregnancyProbabilityConfig,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnablePregnancyModify,
                        o => MCMSettings.Instance.EnablePregnancyModify = o),
                    null)
                .SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddPrionMarriageFertility(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.PrionMarriageFertility, groupBuilder => groupBuilder
                .AddFloatingInteger("PrionPregnancyProbability", CommonText.PrionPregnancyProbability, 0, 100,
                    new ProxyRef<float>(() => MCMSettings.Instance.PrisonPregnancyProbability,
                        o => MCMSettings.Instance.PrisonPregnancyProbability = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("PrisonOnlyPlayerParty", CommonText.PrisonOnlyPlayerParty,
                    new ProxyRef<bool>(() => MCMSettings.Instance.PrisonOnlyPlayerParty,
                        o => MCMSettings.Instance.PrisonOnlyPlayerParty = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddToggle("PrisonPregnancyEnable", CommonText.PrionMarriageFertility,
                    new ProxyRef<bool>(() => MCMSettings.Instance.PrisonPregnancyEnable,
                        o => MCMSettings.Instance.PrisonPregnancyEnable = o), null)
                .SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddChildrenSettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.ChildBecomeHuman, groupBuilder => groupBuilder
                .AddInteger("ChildBecomeHumanDetail", CommonText.ChildBecomeHumanDetail, 1, 300,
                    new ProxyRef<int>(() => MCMSettings.Instance.ChildrenBecomeHumanIncreaseAge,
                        o => MCMSettings.Instance.ChildrenBecomeHumanIncreaseAge = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddToggle("ChildBecomeHuman", CommonText.ChildBecomeHuman,
                    new ProxyRef<bool>(() => MCMSettings.Instance.ChildrenBecomeHuman,
                        o => MCMSettings.Instance.ChildrenBecomeHuman = o),
                    null)
                .SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddDialogSettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.DialogControl, groupBuilder => groupBuilder
                .AddBool("PrisonMarryDialog", CommonText.PrisonMarryDialog,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnablePrisonMarryDialog,
                        o => MCMSettings.Instance.EnablePrisonMarryDialog = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("SexFriendDialog", CommonText.SexFriendDialog,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableSexFriendDialog,
                        o => MCMSettings.Instance.EnableSexFriendDialog = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("SexPregnancyDialog", CommonText.SexPregnancyDialog,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableSexPregnancyDialog,
                        o => MCMSettings.Instance.EnableSexPregnancyDialog = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("RentWifeDialog", CommonText.RentWifeDialog,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableRentWifeDialog,
                        o => MCMSettings.Instance.EnableRentWifeDialog = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("DuelSpouseDialog", CommonText.DuelSpouseDialog,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableDuelSpouseDialog,
                        o => MCMSettings.Instance.EnableDuelSpouseDialog = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("PoemDialog", CommonText.PoemDialog,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnablePoemDialog,
                        o => MCMSettings.Instance.EnablePoemDialog = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddBool("CompetitionQuest", MarriageText.EnableCompetitionQuest.ToString(),
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableCompetitionQuest,
                        o => MCMSettings.Instance.EnableCompetitionQuest = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddPartyLeaveSettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.PartyLeaveConfig, groupBuilder => groupBuilder
                .AddInteger("DaysInTownThreshold", CommonText.DaysInTownThreshold, 1, 10,
                    new ProxyRef<int>(() => MCMSettings.Instance.DaysInTownThreshold,
                        o => MCMSettings.Instance.DaysInTownThreshold = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddInteger("RequestTimeoutDays", CommonText.RequestTimeoutDays, 1, 5,
                    new ProxyRef<int>(() => MCMSettings.Instance.RequestTimeoutDays,
                        o => MCMSettings.Instance.RequestTimeoutDays = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .AddFloatingInteger("EliteTroopRatio", CommonText.EliteTroopRatio, 0f, 100f,
                    new ProxyRef<float>(() => MCMSettings.Instance.EliteTroopRatio,
                        o => MCMSettings.Instance.EliteTroopRatio = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                
                .AddToggle("EnablePartyLeave", CommonText.PartyLeaveConfig,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnablePartyLeave,
                        o => MCMSettings.Instance.EnablePartyLeave = o),
                    null)
                .SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddTournamentSettings(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.TournamentGroupName, groupBuilder => groupBuilder
                .AddBool("TournamentNameShow", CommonText.TournamentNameShowText,
                    new ProxyRef<bool>(() => MCMSettings.Instance.EnableNameShow,
                        o => MCMSettings.Instance.EnableNameShow = o),
                    boolBuilder => boolBuilder.SetRequireRestart(false).SetOrder(orderIndex++)
                ).SetGroupOrder(_groupIndex++)
            );
        }

        public static void AddDefaultSetting(ISettingsBuilder builder, int orderIndex = 0)
        {
            builder.CreateGroup(CommonText.DefaultConfig, groupBuilder => groupBuilder
                .AddBool("firstRun", CommonText.ResetDefaultConfig,
                    new ProxyRef<bool>(() => MCMSettings.Instance.FirstRunDone,
                        o => MCMSettings.Instance.FirstRunDone = o),
                    boolBuilder => boolBuilder.SetRequireRestart(true).SetOrder(orderIndex++)
                )
                .AddBool("FixClanLeader", CommonText.FixClanLeader,
                    new ProxyRef<bool>(() => MCMSettings.Instance.FixClanLeader,
                        o => MCMSettings.Instance.FixClanLeader = o),
                    boolBuilder => boolBuilder.SetOrder(orderIndex++)
                )
                .AddBool("KnowEveryOne", CommonText.KnowEveryOne,
                    new ProxyRef<bool>(() => MCMSettings.Instance.KnowEveryOne,
                        o => MCMSettings.Instance.KnowEveryOne = o),
                    boolBuilder => boolBuilder.SetOrder(orderIndex++)
                )
                .AddInteger("HeroOldAgent", CommonText.HeroOldAge, 47, 10000,
                    new ProxyRef<int>(() => MCMSettings.Instance.HeroOldAge,
                        o => MCMSettings.Instance.HeroOldAge = o),
                    integerBuilder => integerBuilder.SetOrder(orderIndex++))
                .SetGroupOrder(-1)
            );
        }
    }
}